﻿#ifndef IMAGEEDITER_H
#define IMAGEEDITER_H

#include <QWidget>
#include<QTextEdit>

//画图控件,实现在图片上绘画功能

enum ItemType{
    IT_LINE,
    IT_RECTANGLE,
    IT_ROUND,
    IT_ARROW,
    IT_TEXT,
    IT_MOSAIC,
    IT_FACE,
    IT_ARROW2
};

class BaseItem{
public:
    virtual void paint(QPainter& painter) = 0; //画图
    virtual int type() = 0; //类型
};

typedef QSharedPointer<BaseItem> BaseItemPtr;

typedef class myLine:public BaseItem{
public:
    //QPoint startPoint;
    //QPoint endPoint;
    QPainterPath path;
    QColor color;
    int size;

    void paint(QPainter& painter);

    int type(){
        return IT_LINE;
    }
}myLine;

typedef class myRectangle:public BaseItem{
    public:
    QPoint startPoint;
    QPoint endPoint;
    QColor color;
    int size;

    void paint(QPainter& painter);

    int type(){
        return IT_RECTANGLE;
    }
}myRectangle;

typedef class myRound:public BaseItem{
    public:
    QPoint startPoint;
    QPoint endPoint;
    QColor color;
    int size;

    void paint(QPainter& painter); //画图
    int type(){
        return IT_ROUND;
    }
}myRound;

typedef class myArrow:public BaseItem{
    public:
    QPoint startPoint;
    QPoint endPoint;
    QColor color;
    int size;

    void paint(QPainter& painter); //画图
    int type(){
        return IT_ARROW;
    }
}myArrow;

typedef class myArrow2:public BaseItem{
    public:
    QVector<QPoint> points;
    QColor color;
    int size;
    bool closed = false;

    void paint(QPainter& painter); //画图
    int type(){
        return IT_ARROW2;
    }
}myArrow2;

typedef class myText:public BaseItem{
    public:
    QString mText;
    QRect mRect;
    QColor color;
    int size;

    void paint(QPainter& painter); //画图
    int type(){
        return IT_TEXT;
    }
}myText;

typedef struct MosaicInfo{
    QPoint p;
    QColor c;
}MosaicInfo;

class myMosaic:public BaseItem{
public:
    QVector<MosaicInfo> vecMosaic;
    int mosaicWidth;

    void paint(QPainter& painter); //画图
    int type(){
        return IT_MOSAIC;
    }
};

typedef class myFace:public BaseItem {
public:
    QPoint pos;
    QString url;

    void paint(QPainter &painter);

    int type() {
        return IT_FACE;
    }
}myFace;

class ImageEditer : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(int currentSize READ currentSize WRITE setCurrentSize NOTIFY currentSizeChanged)
    Q_PROPERTY(QColor currentColor READ currentColor WRITE setCurrentColor NOTIFY currentColorChanged)
    Q_PROPERTY(bool undoEnable READ undoEnable NOTIFY undoEnableChanged)
public:
    explicit ImageEditer(QWidget *parent = nullptr);

    void setdrawlineenable();
    void setrectangleenable();
    void setdrawarrowenable();
    void setdrawarrow2enable();
    void setroundenable();
    void settexteditenable();
    void settextedittovector();
    void setdrawmosaicnable();
    void setdrawfacenable();
    void setclipable();

    bool isEditing() const;

    void setimagetolabel(const QImage &image);
    void undo();

    QPixmap resultimage();

    QImage HDResultImage(QImage img);

    void updateNow();

    inline int getMosaicWidth(){
        return currentSize() * 2 + 2;
    }

    int currentSize() const
    {
        return m_currentSize;
    }

    QColor currentColor() const
    {
        return m_currentColor;
    }

    bool undoEnable() const
    {
        return items.size() > 0;
    }

    void addItem(BaseItem* itemPtr);

signals:
    void doubleClicked(); //双击
    void cliped(QRect); //图片被剪切

protected:
    void mouseDoubleClickEvent(QMouseEvent* event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;
    void paintEvent(QPaintEvent *event) override;
    bool eventFilter(QObject *watched, QEvent *event) override;

    void doClip();

public slots:
    void ontextchanged();

    void setCurrentSize(int currentSize)
    {
        if (m_currentSize == currentSize)
            return;

        m_currentSize = currentSize;

        QString txt = m_plaintextedit->toPlainText();
        m_plaintextedit->clear();
        m_plaintextedit->setFontPointSize( 8 + 5 *m_currentSize);
        m_plaintextedit->setText(txt);
        emit currentSizeChanged(m_currentSize);
    }

    void setCurrentColor(QColor currentColor)
    {
        if (m_currentColor == currentColor)
            return;

        m_currentColor = currentColor;
        m_plaintextedit->setTextColor(m_currentColor);
        emit currentColorChanged(m_currentColor);
    }

signals:
    void currentSizeChanged(int currentSize);
    void currentColorChanged(QColor currentColor);

    void undoEnableChanged(bool undoEnable);
    
private:
    QColor getAvarageColor(const QPoint& pos);

private:
    QPoint startPoint;
    QPoint endPoint;
    QPoint mosaicLastPoint;

    QRect clipRect;

    //绘图元素
    QVector<BaseItemPtr> items;

    QString text;
    QImage selectimage;
    QTextEdit *m_plaintextedit;
    QVector<MosaicInfo> mosaicPoints;
    QWidget* clipConfirm = nullptr;

    bool ispressed;
    bool isclip;

    bool isdrawline;
    bool isdrawrectangle;
    bool isdrawround;
    bool istextedit;
    bool isdrawarrow;
    bool isdrawarrow2;
    bool isdrawmosaic;
    bool isdrawface;

    int m_currentSize;
    QColor m_currentColor;
};

#endif // IMAGEEDITER_H
